#include "ArmyState.h"
#include "UserAPI.h"
#include "BasicAI.h"
#include "params.h"

using namespace ArmyStateNS;

void ManageState::execute()
{
	BasicAI *ai = BasicAI::instance();
	UserAPI &api = ai->get_api();
	if (!(m_target == Position(-1, -1)))
		if (!api.GetCity(m_target) || api.GetCity(m_target)->owner != api.get_my_id())
			m_target = Position(-1, -1);

	Army *army = api.get_my_army(m_name);

	if (m_target == Position(-1, -1))
	{
		LandCity *city = api.GetNearestMyCity(army->pos);
		if (!city) 
		{
			//	TERRIBLE!!! We have no cities now!!

			switch (api.get_my_army(m_name)->soldierType) {
			case (SOLDIER_INFANTRY):
				//	TODO	complete transition
				enter_state(m_name, new IdleState(m_name));
				return;
			case (SOLDIER_RANGER):
				//	TODO	complete transition
				enter_state(m_name, new IdleState(m_name));
				return;
			case (SOLDIER_CAVALRY):
				//	TODO	complete transition
				enter_state(m_name, new IdleState(m_name));
				return;
			}
			return;
		}

		m_target = api.GetCityCenter(city);
	}

	if (api.InDanger(army->pos))
	{
		if (api.GetCity(army->pos) == api.GetCity(m_target) || api.HamDistance(army->pos, m_target) <= 7)
		{
			enter_state(m_name, new DefensiveBattleState(m_name, m_target));
			return;
		} else
		{
			switch (api.get_my_army(m_name)->soldierType) {
			case (SOLDIER_INFANTRY):
				//	TODO	complete transition
				enter_state(m_name, new IdleState(m_name));
				return;
			case (SOLDIER_RANGER):
				//	TODO	complete transition
				enter_state(m_name, new IdleState(m_name));
				return;
			case (SOLDIER_CAVALRY):
				//	TODO	complete transition
				enter_state(m_name, new IdleState(m_name));
				return;
			}
		}

		return;
	}

	if (api.GetCity(army->pos) != api.GetCity(m_target))
		//	try to move to the city
		api.Move(ai->get_action_queue(), army->pos, m_target);


	LandCity* city = api.GetCity(m_target);
	if (city != NULL) {
		if (city->HP < params::get<int>("HP_LIMIT", 100)) api.RepairCity(ai->get_action_queue(), city);
		if (city->HP > params::get<int>("BARRACK_HP_LIMIT", 50) && !city->hasBarrack) api.BuildBarrack(ai->get_action_queue(), city);

		if (city->hasBarrack)
			api.Recruit(ai->get_action_queue(), params::get<int>("DEFENSIVE_RECRUIT_AMOUNT", 50));
	}
}
